跳到主要内容

模拟赛题解/2025.9.18 模拟赛

· 阅读需 8 分钟
Sintle
Developer

T1-长城(test)

题面

一个长为 nn 的序列 aa 被称为墙壁序列当且仅当满足下列条件:

  • 1i<n1\leq i<n,有 aiai+1a_i\not=a_{i+1}
  • aa 中所有数的异或和为 00

给出 nnmm,求出有多少个长为 nn墙壁序列 满足 0ai<2m0\leq a_i<2^m。答案对 998244353998244353 取模。

1T105,1n,m1091\leq T\leq 10^5,1\leq n,m\leq10^9

题解

注意到一个朴素的思路是第一个数任意选,之后每个数和前一个不同,最后一个固定。

显然会多算最后一位和倒数第二位相同的情况,但此时前 n2n-2xor\text{xor} 和为 00

于是我们设 mm 固定时,前 ii 位和为 00 的情况数为 f(i)f(i),得到递推式:

f(i)={1, if i=10, if i=22m(2m1)i2(2m1)f(i2), if i2f(i)=\begin{cases} 1,\text{ if }i=1\\ 0,\text{ if }i=2\\ 2^m(2^m-1)^{i-2}-(2^m-1)f(i-2),\text{ if }i\geq2 \end{cases}

此时有两种做法:

  1. 矩阵乘法维护 f(i)f(i)(2m1)i(2^m-1)^i 进行转移,矩阵快速幂 O(nlogn)O(n\log n)
  2. 考虑打表,发现一个神奇性质:若设 x=2m1x=2^m-1
f(i)={xi1, if imod2=1xi1+(x)n2, if imod2=0f(i)=\begin{cases} x^{i-1},\text{ if }i\bmod 2=1\\ x^{i-1}+(-x)^\frac n2,\text{ if }i\bmod 2=0 \end{cases}

复杂度同样是 O(nlogn)O(n\log n)

T2-网线(wire)

题面

给定一个字符串 SS,设其长度为 nn,每个字符要么是 +\texttt{+} 要么是 -\texttt{-}

定义一个片段为 SS 的一个子串 S[l,r]S[l,r] 满足下面三个条件:

  • l=1l = 1 或者 Sl1SlS_{l-1} \neq S_l
  • r=nr = n 或者 Sr+1SrS_{r+1} \neq S_r
  • Sl=Sl+1==Sr1=SrS_l = S_{l+1} = \cdots = S_{r-1} = S_r

定义一次变换为:选择 SS 的两个相邻且长度不同的片段,改变长度较小的那个片段的所有字符为其相反字符。(+\texttt{+} 变为 -\texttt{-}-\texttt{-} 变为 +\texttt{+}

现在有 qq 次询问,每次询问会给出只包含 +\texttt{+}-\texttt{-} 并且长度相同的字符串 Si,TiS_i, T_i,请你判断 SiS_i 是否能够通过若干次变换得到 TiT_i

1Si1061\leq \sum|S_i|\leq10^6

题解

注意到每次操作就是把较短的连续段合并进较长的连续段中,所以我们用链表维护连续段。

如果对于 TT 中某一位 1i<n1\leq i<nTiTi+1T_i\not=T_{i+1},除非 Ti=SiT_i=S_iTi+1=Si+1T_{i+1}=S_{i+1},否则一定不可能到达。

除此之外,对于某个 SSTT 相同的连续段,尽量向两边合并显然不劣,因此我们从左向右扫,直接尽量合并。

注意到连续段个数不超过 nn,并且每次合并减少一个,因此复杂度为 O(n)O(n)

T3-里斯(lis)

题面

多组询问,每组给定三个整数 nnaabb

p=(p0,p1,,pn1)p=(p_0,p_1,\cdots,p_{n−1})(0,1,,n1)(0,1,\cdots,n−1) 的一个排列。若 PP 满足以下所有条件, 则称其为墙壁排列:

  • pp 的最长上升子序列的长度不超过 22
  • pa=bp_a=b

请计算墙壁排列的个数,答案对 109+710^9+7 取模。

1T106,1a,bn5×1061\leq T\leq 10^6,1\leq a,b\leq n\leq5\times10^6

题解

考虑 Dilworth 定理,先把题目改成:要求排列 pp 的最小上升子序列剖分 2\leq 2,并且 pA=n+1Bp_A = n+1-B 的方案数。

对于上升子序列剖分有一个经典算法:每次选择末尾最大的一个可以接下一个元素的子序列接下一个,如果没有就新建一个。 如果按这个流程,则每次都会有一个子序列的末尾为前缀最大值,每个元素比其大才会放进对应的子序列。

所以就把前缀最大值放进一个子序列,别的放进另一个。接下来还需要分析性质: 选定前缀最大值为 pi1=v1,pi2=v2,,pik=vkp_{i_1}=v_1, p_{i_2}=v_2,\dots,p_{i_k}=v_k 后,至多对应一个合法排列。

存在的条件是:对于所有 kkvkik+11v_k \geq i_{k+1}-1。额外性质:所有前缀最大值 ii 必然有 piip_i \geq i,其余位置有 pi<ip_i < i

比较难的一步转化:把前缀最大值的直方图画出来,条件等价于直方图的轮廓线一直在 y=xy=x 上方。

若有 n+1BAn+1-B \geq A,则 AA 为一个前缀最大值,可以两边做反射容斥;否则考虑逆排列 q=p1q=p^{-1},求满足 LDSLDS 长度 2\leq 2qn+1B=Aq_{n+1-B}=Aqq,就化归了。

最终复杂度 O(n)O(n)

T4-上课(lesson)

题面

小墙壁在大学里报了两门课,分别在两个不同的教室上课。第 ii 门课有 nin_i 节,第 jj 节的上课时间是 ai,ja_{i,j}bi,jb_{i,j}(不含两端)。保证同一门课的上课时间互不重叠,但是两门课之间的上课时间可能重叠。

小墙壁非常强,只要某节课中的任意短的一段时间范围中(不能为一个时间点),他在上这节课的教室内,他就必定能听懂这节课的内容。然而,他需要 kk 的时间从一个教室走到另一个教室。时刻 00 时,他在第一门课的上课教室。小墙壁想问你,通过合理地在两个教室间往返,他最多能够听懂几节课?

1n3×105,0ai,jbi,j109,1k1091\leq n\leq3\times10^5,0\leq a_{i,j}\leq b_{i,j}\leq 10^9,1\leq k\leq 10^9

题解

将每个 ai,j,bi,ja_{i,j}, b_{i,j} 增加 0.50.5,这样只需要在整数 ±ε\pm \varepsilon 的时刻转场即可,可以钦定转场时间为整数。

首先考虑高复杂度 dp。设 dpi,jdp_{i,j}jj 时刻在 ii 号教室,之前最多上几节课。 如果上个时刻还在该教室,可以直接转移。但如果刚刚经历转场,直接用 dp3i,jk+0/1dp_{3-i, j-k} + 0/1 转移可能是错的,因为可能把现在正在上的课算了两遍。

可以用贪心解决:如果之前在教室 ii 的最后时刻,现在在上的课已经开始,那不如提早前往教室 3i3-i 的时间,因为待在教室 ii 不能获得更多收益。 所以可以钦定不会在教室 ii 上两次同样的课。

如果现在正在上的课开始时间是 tt,就用 dp3i,t1+k+x+0/1dp_{3-i, t-1+k} + x + 0/1 来转移,其中 xx 是在教室 3i3-i 新听的课数,0/10/1 表示教室 ii 是否在上课(如果不在上课,就无此限制)。

显然 dpi,jdp_{i,j}jj 不减且最多为 n1+n2n_1+n_2,且只有 dpi,j>dpi,j1dp_{i,j} > dp_{i,j-1} 的位置是有用的。
考虑从时间维上扫描线,动态维护目前 dp1,j,dp2,jdp_{1,j}, dp_{2,j} 的大小及之前的信息。

第二类转移的限制可改为:对于某个 dpi,jdp_{i,j},如果教室 3i3-ijkj-k 时刻在上课,并且这节课在 tt 时刻下课,那么 dpi,jdp_{i,j} 只能在 max(j+k,t+1)\max(j+k, t+1) 时刻开始才能贡献到其他状态,否则只要 j+kj+k 时刻就可以。

对于转移中的 xx,可以拆成目标时刻 k-k 前已上课数减去时刻 jj 前已上课数,所以只需要记录最大的 dpi,jdp_{i,j} 减去时刻 jj 前课数。

转移方程发生变化只会是以下几种情况之一:

  • 一节课开始;
  • 一节课结束;
  • 一个新的第二类转移被允许;
  • kk 时刻前一节课开始(因为第二类转移中的 xx 会增加一)。

总量是 O(n)O(n) 的。用 priority_queue\text{priority\_queue} 按时间顺序更新转移即可。

另一种做法是尝试从小到大依次二分出 dpi,j>dpi,j1dp_{i,j} > dp_{i,j-1} 的位置,或者直接设 dpi,j,0/1dp_{i,j,0/1} 表示在教室 ii,时刻 jj,对面正在上的课是否上过,这些做法也都是可行的。